#include <iostream>

// template<class T>
// class Singleton
// {
//     static T data;
//     public:
//       static T* GetInstance()
//       {
//         return &data;
//       }
// };

// template<class T>
// class Singleton
// {
//     static T* data;
// public:
//     static T* GetInstance()
//     {
//         if(data==nullptr)
//         {
//             data= new T;
//         }
//         return data;
//     }
// };
#include <mutex>
#include <string>

namespace SingleMouble
{
    template <class T>
    class Singleton
    {
         static T *data; // 这里需要协商volatile 不然会被编译器优化掉
        static std::mutex lock;  // C++ 自己的锁

    public:
        static T *GetInstance()
        {
            if (data == nullptr)                       // 先判断在上锁，如果把锁写到前面，那么每次一次调用都将成为串行，降低了效率
            {                                          // 这样双重判空指针，降低了锁冲突的概率，提高了性能。
                std::lock_guard<std::mutex> mux(lock); // C++ 自己的RAII 生命锁
                if (data == nullptr)                   // 互斥锁，在多个线程进来的时候，也能保证只有一个线程new上了。
                {
                    data = new T;
                }
            }
            return data;
        }
    };
}
